package com.ebelter.btlibrary.btble.impl.scale;

import android.os.Handler;
import android.os.HandlerThread;
import android.os.SystemClock;

import com.ebelter.btlibrary.btble.ble.bluetooth.device.impl.BleCommandEditor;
import com.ebelter.btlibrary.btble.ble.model.BtAck;
import com.ebelter.btlibrary.btble.impl.scale.common.ScaleAck;
import com.ebelter.btlibrary.btble.impl.scale.model.ScaleCommand;
import com.ebelter.btlibrary.btble.impl.scale.model.ScaleUser;
import com.ebelter.btlibrary.btble.util.BytesUtils;
import com.ebelter.btlibrary.btble.util.TimeUtils;
import com.ebelter.btlibrary.util.ULog;

import java.util.Arrays;
import java.util.Calendar;
import java.util.concurrent.TimeUnit;

/**
 * 体脂秤指令编辑器实现层
 * Created by Sergio Pan on 2017/12/8.
 */

public class ScaleCommondEditor extends BleCommandEditor {

    private static final String TAG = "ScaleCommondEditor";

    private static ScaleCommondEditor instance = new ScaleCommondEditor();

    //心跳线程用

    public long sendDataTime = 0;
    private int sendDataTimeout = 2000;

    private ScaleCommondEditor() {}
    public static ScaleCommondEditor getInstance() {
        return instance;
    }


    //
   // private final byte[] deviceAddressBytes = new byte[]{0x16, 0x15, 0x14, 0x13, 0x12, 0x11};

//    @Override
//    protected byte[] encrypt(byte[] data) {
//        ULog.i(TAG, "----encript--- before --data = " + BytesUtils.bytes2HexStr(data));
//        if ((data[0] & 0xff) == (dataHeaderSend&0xff)) {
//            byte[] macAddr = deviceAddressBytes;
//            for (int i = 3, j = 0; i < data.length; i++, j++) {
//                data[i] ^= macAddr[j % 6];
//            }
//        }
//        ULog.i(TAG, "----encript-----data = " + BytesUtils.bytes2HexStr(data));
//        return data;
//    }

    /**
     * 设置秤用户信息
     */
    public void setUserInfo(ScaleUser user) {
        byte[] userInfo = user.buildScaleUserData();
        ULog.i(TAG, "----下发用户信息----user = " + user+"---"+BytesUtils.bytes2HexStr(userInfo));
        sendResquest("设置秤用户信息", userInfo);
    }


    /**
     * 下发删除所有用户指令
     */
    public void requestDelAllUser() {
        ULog.i(TAG, "send delete all user list cmd.");
        byte[] bytes = {
                dataHeaderSend,
                0x02,
                (byte) 0xa1,
                0x00
        };
        sendResquest("清除所有用户",bytes);
    }




    /**
     * 下发同步系统时间命令
     */
    public void syncSystemClock() {
        ULog.i(TAG, "----同步时钟信息----");
        Calendar cal = Calendar.getInstance();
        int year = cal.get(Calendar.YEAR);
        int month = cal.get(Calendar.MONTH) + 1;
        int date = cal.get(Calendar.DATE);
        int hour = cal.get(Calendar.HOUR_OF_DAY);
        int minute = cal.get(Calendar.MINUTE);
        int second = cal.get(Calendar.SECOND);

//        setClockTime = cal.getTimeInMillis();

        //TODO 需要确认
        //周一至周日，1至7
        int week = cal.get(Calendar.DAY_OF_WEEK);
        week = (week == 1) ? 7 : (week - 1);

        int yearLowHex = year & 0xff;
        int yearHeightHex = (year >> 8) & 0xff;

        ULog.i(TAG,"year="+year+"--yearLowHex="+yearLowHex+"--yearHeightHex="+yearHeightHex+"--month="+month
                +"--date="+date+"--hour="+hour+"--minute="+minute+"--second="+second+"--week="+week);
        byte[] bytes = {
                dataHeaderSend,
                0x09,
                (byte) 0x98,
                (byte) yearLowHex,
                (byte) yearHeightHex,
                (byte) month,
                (byte) date,
                (byte) hour,
                (byte) minute,
                (byte) second,
                (byte) week

        };

        sendResquest("同步系统时间命令", bytes);
    }


    /**
     * 请求历史记录
     */
    public void requestHistoryRecords(String uid) {
        ULog.i(TAG, "----请求历史数据-----request History Records cmd, uid is : " + uid);
        String[] uidArr = uid.split(":");

        if (uidArr.length != 7) {
            uidArr = new String[]{"0", "0", "0", "0", "0", "0", "0"};
        }
        byte[] bytes = {
                dataHeaderSend,
                0x07,
                (byte) 0x9b,
                (byte) Integer.parseInt(uidArr[0], 16),
                (byte) Integer.parseInt(uidArr[1], 16),
                (byte) Integer.parseInt(uidArr[2], 16),
                (byte) Integer.parseInt(uidArr[3], 16),
                (byte) Integer.parseInt(uidArr[4], 16),
                (byte) Integer.parseInt(uidArr[5], 16),
                (byte) Integer.parseInt(uidArr[6], 16),
                0x00
        };
        ULog.i(TAG, "------requestHistoryRecords------ cmd = " + BytesUtils.bytes2HexStr(bytes));
        sendResquest("请求历史数据", bytes);
    }

    /**
     * 下发查询版本
     */
    public void requestScaleVersion() {
        ULog.i(TAG, "----requestScaleVersion------send get version cmd.");
        byte[] bytes = {
                dataHeaderSend,
                0x01,
                (byte) 0x9c
        };
        sendResquest("下发查询版本",bytes);
    }

    /**
     * 下发OTA分包数据
     * 2017-02-11
     *
     * @param bs    数据包内容
     * @param pkgNo 第N个包
     */
    public void sendOTAPackage(byte[] bs, int pkgNo) {
        ULog.i(TAG, "-----sendOTAPackage----send ota package data cmd.");
        int bsLen = bs.length;
        ULog.i(TAG, "pkg data len:" + bsLen + ",data is : " + Arrays.toString(bs));
        //包号，总包数大，一个字节存不完，需分高8位，低8位
        int noLowHex = pkgNo & 0xff;
        int noHeightHex = (pkgNo >> 8) & 0xff;
        //bytes为传输的数据包，第0个字节为包头，第1个为指令，第2--3个为包号，
        byte[] bytes = new byte[20];
        bytes[0] = (byte) 0xad;
        bytes[1] = (byte) 0x12;
        bytes[2] = (byte) noLowHex;
        bytes[3] = (byte) noHeightHex;

        //第4--19个为数据，数据长度不够16，则用0xff填充
        for (int i = 4, j = 0; i < 20; i++, j++) {
            if (j >= bsLen) {
                bytes[i] = (byte) 0xff;
            } else {
                bytes[i] = bs[j];
            }
        }


        //后18位做xor亦或校验，存入bytes[1]
        byte csXor = 0;
        for (int i = 2; i < bytes.length; i++) {
            csXor ^= bytes[i];
        }
        bytes[1] = csXor;
        //Fat Body协议修改
        bytes[2] = (byte) (((pkgNo & 0xff) + 0x90) & 0xff);
//		bytes[21] = 0x11;
//		bytes[22] = 0x00;

        sendResquest("下发OTA分包数据", bytes);
    }


    //下发OTA请求升级(2017-05-05新增，crc8校验）

    /**
     * @param type   01:蓝牙固件,02：秤固件
     * @param pkgLen 整包长度
     * @param cs  CRC8校验值
     */
    public void sendOTAUpdateRequestCRC(int type, int pkgLen, int cs) {
        ULog.i(TAG, "send ota updarge request cmd. cs:" + Integer.toHexString(cs));
        int lenLowHex = pkgLen & 0xff;
        int lenHeightHex = (pkgLen >> 8) & 0xff;

        byte[] bytes = {
                dataHeaderSend,
                0x06,
                (byte) 0x9d,
                (byte) type,
                (byte) lenLowHex,
                (byte) lenHeightHex,
                (byte) cs,
                0
        };

        sendResquest("sendOTAUpdateRequestCRC",bytes);
    }


    private HeartThread mHeartThread;
    /**
     * 开始发送心跳包
     */
    public void startConnHeartbeat() {
        ULog.i(TAG, "-----startConnHeartbeat----");
        if (mHeartThread == null) {
            mHeartThread=new HeartThread();
            sendHeartThreadStart=true;
            mHeartThread.start();
        }

    }

    /**
     * 停止心跳
     */
    public void stopConnHeartbeat() {
        sendHeartThreadStart=false;
        mHeartThread=null;
    }
    public boolean sendHeartThreadStart = true;

    private class HeartThread extends Thread{
        @Override
        public void run() {
            while (sendHeartThreadStart){
                if (System.currentTimeMillis() - sendDataTime >= sendDataTimeout) {
                    ULog.i(TAG,"发送了一个心跳包 sendDataTime"+TimeUtils.formatTime1(sendDataTime));
                    sendHeartBeatCmd();
                }
                SystemClock.sleep(2000);
            }
        }
    }



    /**
     * 下发心跳指令
     */
    public void sendHeartBeatCmd() {
        ULog.d(TAG, "send bt heartbeat cmd.");

        byte[] bytes = {
                dataHeaderSend,
                0x01,
                (byte) 0xb0
        };

        this.sendBleMessage("下发心跳指令",bytes);
    }




    @Override
    protected void onReceiveCommand(Object command) {
        ScaleCommand scaleCommand = (ScaleCommand) command;
        ULog.i(TAG, "-------onReceiveCommand-------scaleCommand = " + scaleCommand);
        switch (scaleCommand) {
            case SYNC_CLOCK:    //同步时钟
                syncSystemClock();
                break;
                case HEART_BEART:    //发心跳
                startConnHeartbeat();
                break;
            case REQUEST_HISTORY_DATA:  //请求历史数据
                break;
        }
    }

    private static final byte[] getHistoryDataACK= {(byte) 0xab, 0x02, (byte) 0x9b, 0x01};
    public void sendGetHistoryACK() {//历史数据的ACK
        ULog.i(TAG,"接收到历史数据---回ack");
        sendResquest("-历史数据---回ACK-"+ TimeUtils.getCurrentTime2(), getHistoryDataACK);
    }

    private static final byte[] getMesureDataACK= {(byte) 0xab, 0x02, (byte) 0xa3, 0x00};
    public void sendMesureACK() {
        ULog.i(TAG,"接收到测量数据---回ack");
        sendResquest("-测量---回ACK-", getMesureDataACK);
    }

    //发送休眠时间
    public void sendSleepTime() {
        byte[] bytes = {
                (byte) 0xab,
                0x03,
                (byte) 0xa2, 0x75,0};
        sendResquest("设置息屏休眠时间", bytes);
        ULog.i(TAG,"-----发送休眠时间断开");
    }

    public void sendDisconnectCmd(){
        byte[] bytes = {
                (byte) 0xab,
                0x01,
                (byte) 0xa6};
        sendResquest("发送让秤断开指令", bytes);
        ULog.i(TAG,"-----发送让秤断开指令");
    }
}
